using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Firestarter.DB.Schema.BO;
using Firestarter.DB.Schema.Test.Logic;
using FireStarterModeller.BO;
using Firestarter.DB.Schema.UI;
using FireStarterModeller.Test;
using FireStarterModeller.Test.BO;
using FireStarterModeller.Test.UI;
using Habanero.Base;
using Habanero.Faces.Base;
using Habanero.Testability;
using NUnit.Framework;

namespace Firestarter.DB.Schema.Test.UI
{
    [TestFixture]
    public class TestChooseDatabaseConnectionWizardStep : TestBase
    {

        [Test]
        [Ignore("For Visual Testing")]
        public void Test__Visually()
        {
            //---------------Set up test pack-------------------
            var wizardStep = new ChooseDatabaseConnectionWizardStep();
            var reverseEngineering = new ReverseEngineering { DatabaseConnectionInfo = new DatabaseConnectionInfo() };
            wizardStep.ReverseEngineering = reverseEngineering;
            //---------------Assert Precondition----------------
            //---------------Execute Test ----------------------
            TestUtilsUI.ShowInVisualTestingForm(GlobalUIRegistry.ControlFactory, wizardStep, DockStyle.Fill);
            //---------------Test Result -----------------------
        }

        [Test]
        public void Test_ReverseEngineering()
        {
            //---------------Set up test pack-------------------
            ChooseDatabaseConnectionWizardStep wizardStep = new ChooseDatabaseConnectionWizardStep();
            ReverseEngineering reverseEngineering = new ReverseEngineering{DatabaseConnectionInfo = new DatabaseConnectionInfo()};
            //-------------Assert Preconditions -------------

            //---------------Execute Test ----------------------
            wizardStep.ReverseEngineering = reverseEngineering;
            //---------------Test Result -----------------------
            Assert.AreSame(reverseEngineering, wizardStep.ReverseEngineering);
            Assert.AreSame(reverseEngineering.DatabaseConnectionInfo, wizardStep.DatabaseConnectionInfo);
            Assert.AreSame(reverseEngineering.DatabaseConnectionInfo, wizardStep.DatabaseConnectionInfoControl.CurrentBusinessObject);
        }

        [Test]
        public void Test_ReverseEngineering_SetToNull()
        {
            //---------------Set up test pack-------------------
            ChooseDatabaseConnectionWizardStep wizardStep = new ChooseDatabaseConnectionWizardStep();
            wizardStep.ReverseEngineering = new ReverseEngineering { DatabaseConnectionInfo = new DatabaseConnectionInfo() };
            //-------------Assert Preconditions -------------
            Assert.IsNotNull(wizardStep.ReverseEngineering);
            Assert.IsNotNull(wizardStep.DatabaseConnectionInfo);
            Assert.IsNotNull(wizardStep.DatabaseConnectionInfoControl.CurrentBusinessObject);
            //---------------Execute Test ----------------------
            wizardStep.ReverseEngineering = null;
            //---------------Test Result -----------------------
            Assert.IsNull(wizardStep.ReverseEngineering);
            Assert.IsNull(wizardStep.DatabaseConnectionInfo);
            Assert.IsNull(wizardStep.DatabaseConnectionInfoControl.CurrentBusinessObject);
        }

        [Test]
        public void Test_DatabaseConnectionInfo_Changed()
        {
            //---------------Set up test pack-------------------
            ChooseDatabaseConnectionWizardStep wizardStep = new ChooseDatabaseConnectionWizardStep();
            ReverseEngineering reverseEngineering = new ReverseEngineering();
            wizardStep.ReverseEngineering = reverseEngineering;
            DatabaseConnectionInfo databaseConnectionInfo = new DatabaseConnectionInfo();
            //-------------Assert Preconditions -------------
            Assert.IsNotNull(wizardStep.ReverseEngineering);
            Assert.IsNull(wizardStep.DatabaseConnectionInfo);
            Assert.IsNull(wizardStep.DatabaseConnectionInfoControl.CurrentBusinessObject);
            //---------------Execute Test ----------------------
            reverseEngineering.DatabaseConnectionInfo = databaseConnectionInfo;
            //---------------Test Result -----------------------
            Assert.AreSame(reverseEngineering, wizardStep.ReverseEngineering);
            Assert.AreSame(databaseConnectionInfo, wizardStep.DatabaseConnectionInfo);
            Assert.AreSame(databaseConnectionInfo, wizardStep.DatabaseConnectionInfoControl.CurrentBusinessObject);
        }

        [Test]
        public void Test_CancelStep_WhenDirtyConnection_ShouldCancelChanges()
        {
            //---------------Set up test pack-------------------
            ChooseDatabaseConnectionWizardStep wizardStep = new ChooseDatabaseConnectionWizardStep();
            ReverseEngineering reverseEngineering = new ReverseEngineering();
            DatabaseConnectionInfo databaseConnectionInfo = TestUtilsDatabaseConnectionInfo.CreateSavedDatabaseConnectionInfo();
            reverseEngineering.DatabaseConnectionInfo = databaseConnectionInfo;
            wizardStep.ReverseEngineering = reverseEngineering;
            databaseConnectionInfo.UserName = GetRandomString();
            //-------------Assert Preconditions -------------
            Assert.AreSame(reverseEngineering, wizardStep.ReverseEngineering);
            Assert.AreSame(databaseConnectionInfo, wizardStep.DatabaseConnectionInfo);
            Assert.AreSame(databaseConnectionInfo, wizardStep.DatabaseConnectionInfoControl.CurrentBusinessObject);
            Assert.IsTrue(databaseConnectionInfo.Status.IsDirty);
            //---------------Execute Test ----------------------
            wizardStep.CancelStep();
            //---------------Test Result -----------------------
            Assert.IsFalse(databaseConnectionInfo.Status.IsDirty);
        }


        [Test]
        public void Test_CancelStep_WhenNullConnection_ShouldDoNothing()
        {
            //---------------Set up test pack-------------------
            ChooseDatabaseConnectionWizardStep wizardStep = new ChooseDatabaseConnectionWizardStep();
            ReverseEngineering reverseEngineering = new ReverseEngineering();
            reverseEngineering.DatabaseConnectionInfo = null;
            wizardStep.ReverseEngineering = reverseEngineering;
             //-------------Assert Preconditions -------------
            Assert.AreSame(reverseEngineering, wizardStep.ReverseEngineering);
            Assert.IsNull(reverseEngineering.DatabaseConnectionInfo);
            Assert.IsNull(wizardStep.DatabaseConnectionInfo);
            //---------------Execute Test ----------------------
            wizardStep.CancelStep();
            //---------------Test Result -----------------------
            Assert.AreSame(reverseEngineering, wizardStep.ReverseEngineering);
            Assert.IsNull(reverseEngineering.DatabaseConnectionInfo);
            Assert.IsNull(wizardStep.DatabaseConnectionInfo);
        }   
     
        [Test]
        public void Test_CancelStep_WhenNullRevEng_ShouldDoNothing()
        {
            //---------------Set up test pack-------------------
            ChooseDatabaseConnectionWizardStep wizardStep = new ChooseDatabaseConnectionWizardStep();
            wizardStep.ReverseEngineering = null;
             //-------------Assert Preconditions -------------
            Assert.IsNull(wizardStep.ReverseEngineering);
            Assert.IsNull(wizardStep.DatabaseConnectionInfo);
            //---------------Execute Test ----------------------
            wizardStep.CancelStep();
            //---------------Test Result -----------------------
            Assert.IsNull(wizardStep.ReverseEngineering);
            Assert.IsNull(wizardStep.DatabaseConnectionInfo);
        }

        [Test]
        public void Test_CancelStep_WhenNewConnection_ShouldCancelChanges()
        {
            //---------------Set up test pack-------------------
            ChooseDatabaseConnectionWizardStep wizardStep = new ChooseDatabaseConnectionWizardStep();
            ReverseEngineering reverseEngineering = new ReverseEngineering();
            DatabaseConnectionInfo databaseConnectionInfo = new DatabaseConnectionInfo();
            reverseEngineering.DatabaseConnectionInfo = databaseConnectionInfo;
            wizardStep.ReverseEngineering = reverseEngineering;
            databaseConnectionInfo.UserName = GetRandomString();
            //-------------Assert Preconditions -------------
            Assert.AreSame(reverseEngineering, wizardStep.ReverseEngineering);
            Assert.AreSame(databaseConnectionInfo, wizardStep.DatabaseConnectionInfo);
            Assert.AreSame(databaseConnectionInfo, wizardStep.DatabaseConnectionInfoControl.CurrentBusinessObject);
            Assert.IsTrue(databaseConnectionInfo.Status.IsDirty);
            Assert.IsTrue(databaseConnectionInfo.Status.IsNew);
            //---------------Execute Test ----------------------
            wizardStep.CancelStep();
            //---------------Test Result -----------------------
            Assert.IsFalse(databaseConnectionInfo.Status.IsDirty);
            Assert.IsTrue(databaseConnectionInfo.Status.IsNew);
            Assert.IsNull(databaseConnectionInfo.UserName);
        }

        [Test]
        public void Test_CancelStep_WhenUnChangedConnection_ShouldDoNothing()
        {
            //---------------Set up test pack-------------------
            ChooseDatabaseConnectionWizardStep wizardStep = new ChooseDatabaseConnectionWizardStep();
            ReverseEngineering reverseEngineering = new ReverseEngineering();
            DatabaseConnectionInfo databaseConnectionInfo = TestUtilsDatabaseConnectionInfo.CreateSavedDatabaseConnectionInfo();
            reverseEngineering.DatabaseConnectionInfo = databaseConnectionInfo;
            databaseConnectionInfo.Save();
            wizardStep.ReverseEngineering = reverseEngineering;
            //-------------Assert Preconditions -------------
            Assert.AreSame(reverseEngineering, wizardStep.ReverseEngineering);
            Assert.AreSame(databaseConnectionInfo, wizardStep.DatabaseConnectionInfo);
            Assert.AreSame(databaseConnectionInfo, wizardStep.DatabaseConnectionInfoControl.CurrentBusinessObject);
            Assert.IsFalse(databaseConnectionInfo.Status.IsDirty);
            Assert.IsFalse(databaseConnectionInfo.Status.IsNew);
            //---------------Execute Test ----------------------
            wizardStep.CancelStep();
            //---------------Test Result -----------------------
            Assert.IsFalse(databaseConnectionInfo.Status.IsDirty);
            Assert.IsFalse(databaseConnectionInfo.Status.IsNew);
        }        
        


        [Test]
        public void Test_DatabaseConnectionInfo_Changed_ToNull()
        {
            //---------------Set up test pack-------------------
            ChooseDatabaseConnectionWizardStep wizardStep = new ChooseDatabaseConnectionWizardStep();
            ReverseEngineering reverseEngineering = new ReverseEngineering { DatabaseConnectionInfo = new DatabaseConnectionInfo() };
            wizardStep.ReverseEngineering = reverseEngineering;
            //-------------Assert Preconditions -------------
            Assert.IsNotNull(wizardStep.ReverseEngineering);
            Assert.IsNotNull(wizardStep.DatabaseConnectionInfo);
            Assert.IsNotNull(wizardStep.DatabaseConnectionInfoControl.CurrentBusinessObject);
            //---------------Execute Test ----------------------
            reverseEngineering.DatabaseConnectionInfo = null;
            //---------------Test Result -----------------------
            Assert.AreSame(reverseEngineering, wizardStep.ReverseEngineering);
            Assert.IsNotNull(wizardStep.ReverseEngineering);
            Assert.IsNull(wizardStep.DatabaseConnectionInfo);
            Assert.IsNull(wizardStep.DatabaseConnectionInfoControl.CurrentBusinessObject);
        }

        [Test]
        public void Test_CanMoveOn_Fails_WithEmptyConnection()
        {
            //---------------Set up test pack-------------------
            ChooseDatabaseConnectionWizardStep wizardStep = new ChooseDatabaseConnectionWizardStep();
            DatabaseConnectionInfo databaseConnectionInfo = new DatabaseConnectionInfo();
            wizardStep.ReverseEngineering = new ReverseEngineering { DatabaseConnectionInfo = databaseConnectionInfo };
            //-------------Assert Preconditions -------------
            Assert.AreSame(databaseConnectionInfo, wizardStep.DatabaseConnectionInfo);
            //---------------Execute Test ----------------------
            string message;
            bool canMoveOn = wizardStep.CanMoveOn(out message);
            //---------------Test Result -----------------------
            Assert.IsFalse(canMoveOn);
            StringAssert.AreEqualIgnoringCase(DatabaseConnectionInfo.SelectVendorMessage, message);
        }

        [Test]
        public void Test_CanMoveOn_Fails_WithEmptyConnectionParameters()
        {
            //---------------Set up test pack-------------------
            ChooseDatabaseConnectionWizardStep wizardStep = new ChooseDatabaseConnectionWizardStep();
            DatabaseConnectionInfo databaseConnectionInfo = new DatabaseConnectionInfo { Vendor = "MySql" };
            wizardStep.ReverseEngineering = new ReverseEngineering { DatabaseConnectionInfo = databaseConnectionInfo };
            //-------------Assert Preconditions -------------
            Assert.AreSame(databaseConnectionInfo, wizardStep.DatabaseConnectionInfo);
            //---------------Execute Test ----------------------
            string message;
            bool canMoveOn = wizardStep.CanMoveOn(out message);
            //---------------Test Result -----------------------
            Assert.IsFalse(canMoveOn);
            StringAssert.StartsWith(DatabaseConnectionInfo.InvalidConnectionMessage, message);
            StringAssert.Contains("The server, database and userName of a connect string can never be empty.", message);
        }

        [Test]
        public void Test_CanMoveOn_Fails_WithNullConnection()
        {
            //---------------Set up test pack-------------------
            ChooseDatabaseConnectionWizardStep wizardStep = new ChooseDatabaseConnectionWizardStep();
            wizardStep.ReverseEngineering = new ReverseEngineering { DatabaseConnectionInfo = null };
            //-------------Assert Preconditions -------------
            Assert.AreSame(null, wizardStep.DatabaseConnectionInfo);
            //---------------Execute Test ----------------------
            string message;
            bool canMoveOn = wizardStep.CanMoveOn(out message);
            //---------------Test Result -----------------------
            Assert.IsFalse(canMoveOn);
            StringAssert.AreEqualIgnoringCase(ChooseDatabaseConnectionWizardStep.SelectConnectionMessage, message);
        }

        [Test]
        public void Test_CanMoveOn_Fails_WithInvalidConnection()
        {
            //---------------Set up test pack-------------------
            ChooseDatabaseConnectionWizardStep wizardStep = new ChooseDatabaseConnectionWizardStep();
            DatabaseConnectionInfo databaseConnectionInfo = new DatabaseConnectionInfo
            {
                Vendor = "MySql",
                Server = "localhost",
                Database = GetRandomString(),
                UserName = "root",
                Password = "root"
            };
            wizardStep.ReverseEngineering = new ReverseEngineering { DatabaseConnectionInfo = databaseConnectionInfo };
            //-------------Assert Preconditions -------------
            Assert.AreSame(databaseConnectionInfo, wizardStep.DatabaseConnectionInfo);
            //---------------Execute Test ----------------------
            string message;
            bool canMoveOn = wizardStep.CanMoveOn(out message);
            //---------------Test Result -----------------------
            Assert.IsFalse(canMoveOn);
            StringAssert.StartsWith(DatabaseConnectionInfo.ConnectionFailedMessage, message);
            //StringAssert.Contains(databaseConnectionInfo.Database, message);
        }

        [Test]
        public void Test_CanMoveOn_Passes_WithValidConnection()
        {
            //---------------Set up test pack-------------------
            ChooseDatabaseConnectionWizardStep wizardStep = new ChooseDatabaseConnectionWizardStep();
            DatabaseConnectionInfo databaseConnectionInfo = TestUtilsDBSchema.CreateValidDatabaseConnectionInfo();
            wizardStep.ReverseEngineering = new ReverseEngineering { DatabaseConnectionInfo = databaseConnectionInfo };
            //-------------Assert Preconditions -------------
            Assert.AreSame(databaseConnectionInfo, wizardStep.DatabaseConnectionInfo);
            //---------------Execute Test ----------------------
            string message;
            bool canMoveOn = wizardStep.CanMoveOn(out message);
            //---------------Test Result -----------------------
            Assert.IsTrue(canMoveOn);
            Assert.IsNull(message);
        }

        private string GetRandomString()
        {
            return RandomValueGen.GetRandomString();
        }
    }
}
